Removing an old, cherished, yet pointless caveat "This documentation is
[supercollider.git] / Help / Streams-Patterns-Events / A Practical Guide / PG_06f_Server_Control.html
blobe9c45914de652f27cb81c465d5a9a8b562d4c23b
1 <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
2 <html>
3 <head>
4 <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
5 <meta http-equiv="Content-Style-Type" content="text/css">
6 <title></title>
7 <meta name="Generator" content="Cocoa HTML Writer">
8 <meta name="CocoaVersion" content="1038.25">
9 <style type="text/css">
10 p.p1 {margin: 0.0px 0.0px 0.0px 0.0px; font: 18.0px Helvetica}
11 p.p2 {margin: 0.0px 0.0px 0.0px 0.0px; font: 12.0px Helvetica; min-height: 14.0px}
12 p.p3 {margin: 0.0px 0.0px 0.0px 0.0px; font: 12.0px Helvetica}
13 p.p4 {margin: 0.0px 0.0px 0.0px 0.0px; font: 12.0px Helvetica; color: #0000bf}
14 p.p5 {margin: 0.0px 0.0px 0.0px 0.0px; font: 12.0px Helvetica; color: #bf0000}
15 p.p6 {margin: 0.0px 0.0px 0.0px 0.0px; font: 12.0px Helvetica; color: #007300}
16 p.p7 {margin: 0.0px 0.0px 0.0px 0.0px; font: 9.0px Monaco; color: #bf0000}
17 p.p8 {margin: 0.0px 0.0px 0.0px 0.0px; font: 9.0px Monaco; min-height: 12.0px}
18 p.p9 {margin: 0.0px 0.0px 0.0px 0.0px; font: 9.0px Monaco}
19 p.p10 {margin: 0.0px 0.0px 0.0px 0.0px; font: 9.0px Monaco; color: #0000bf}
20 p.p11 {margin: 0.0px 0.0px 0.0px 0.0px; font: 9.0px Monaco; color: #007300}
21 p.p12 {margin: 0.0px 0.0px 0.0px 0.0px; font: 14.0px Helvetica}
22 p.p13 {margin: 0.0px 0.0px 0.0px 0.0px; font: 12.0px Helvetica; color: #0000ee}
23 li.li3 {margin: 0.0px 0.0px 0.0px 0.0px; font: 12.0px Helvetica}
24 span.s1 {color: #0000bf}
25 span.s2 {color: #007300}
26 span.s3 {color: #000000}
27 span.s4 {color: #606060}
28 span.s5 {color: #bf0000}
29 span.s6 {text-decoration: underline}
30 span.Apple-tab-span {white-space:pre}
31 ul.ul1 {list-style-type: disc}
32 </style>
33 </head>
34 <body>
35 <p class="p1"><b>Server control methods</b></p>
36 <p class="p2"><br></p>
37 <p class="p3">A handful of filter patterns can isolate signals on a private bus and/or group, and also apply effect synths. A nice feature is that resources allocated at the beginning of the pattern are removed at the end. This is especially useful for effects, where you don't want to have a lot of effect synths left over taking up CPU but not processing audio.</p>
38 <p class="p2"><br></p>
39 <ul class="ul1">
40 <li class="li3"><b>Pbus(pattern, dur, fadeTime, numChannels, rate):</b> Creates a private group and bus for the synths played by the pattern. The group and bus are released when the pattern stops. Useful for isolating signals from different patterns.</li>
41 <li class="li3"><b>Pgroup(pattern):</b> Creates a private group (without private bus) for the pattern's synths.</li>
42 </ul>
43 <p class="p2"><br></p>
44 <ul class="ul1">
45 <li class="li3"><b>Pfx(pattern, fxname, pairs)</b></li>
46 <li class="li3"><b>Pfxb(pattern, fxname, pairs):</b> Both of these patterns play an effect synth at the tail of the target group. This synth should read from the bus identified by the 'out' argument, and write the processed signal onto the same bus using either ReplaceOut or XOut. Pfx uses whatever bus and group are specified in the incoming event. Pfxb allocates a separate bus and group for the effect and the pattern.</li>
47 </ul>
48 <p class="p2"><br></p>
49 <p class="p3">There are a lot of permutations when it comes to signal routing and effect management, too many to discuss in depth here. Some of the main scenarios are:</p>
50 <p class="p2"><br></p>
51 <ul class="ul1">
52 <li class="li3">Separate effects that should apply individually: the patterns and effects should be isolated on separate buses. <a href="../Patterns/Pfxb.html"><span class="s1">Pfxb</span></a> handles this isolation automatically: two patterns like <span class="s1">Pfxb</span>(<span class="s1">Pbind</span>(...), <span class="s2">\fxname</span>, <span class="s2">\effectargName</span>, value, <span class="s2">\name</span>, value...) will play on separate buses and their signals will not interfere with each other.</li>
53 </ul>
54 <p class="p2"><br></p>
55 <ul class="ul1">
56 <li class="li3">Effects that should apply as a chain: both effects should use the same bus, and the effect patterns should be nested to string them together. The outermost effect should use Pfxb to allocate a separate group and bus for this signal chain; inner ones should use <a href="../Patterns/Pfx.html"><span class="s1">Pfx</span></a> to piggyback on the existing bus.</li>
57 </ul>
58 <p class="p2"><br></p>
59 <p class="p4">Pfxb<span class="s3">(</span></p>
60 <p class="p4"><span class="s3"><span class="Apple-tab-span"> </span></span>Pfx<span class="s3">(</span></p>
61 <p class="p5"><span class="s3"><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span></span>(event pattern here),</p>
62 <p class="p6"><span class="s3"><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span></span>\synthDefNameOfFirstEffectInChain<span class="s3">,</span></p>
63 <p class="p5"><span class="s3"><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span></span>(argument list for the first effect),</p>
64 <p class="p3"><span class="Apple-tab-span"> </span>)</p>
65 <p class="p6"><span class="s3"><span class="Apple-tab-span"> </span></span>\synthDefNameOfSecondEffectInChain<span class="s3">,</span></p>
66 <p class="p5"><span class="s3"><span class="Apple-tab-span"> </span></span>(argument list for the second effect)</p>
67 <p class="p3">).play;</p>
68 <p class="p2"><br></p>
69 <p class="p3">More complex arrangements are possible through nesting, and parallelizing Pfx or Pfxb patterns using <a href="../Patterns/Ppar.html"><span class="s1">Ppar</span></a> and its cousins.<span class="Apple-converted-space"> </span></p>
70 <p class="p2"><br></p>
71 <p class="p3">This example uses Pfxb to isolate a pair of separately-sounding patterns on different buses, and to pass the two signals' streams through separate volume controls. The effect synth, for volume, is kept deliberately simple for the example, but of course it can do any kind of signal processing you like.</p>
72 <p class="p2"><br></p>
73 <p class="p3">It might seem odd at first to use a gated envelope for an effect, but this is important to keep the signal's integrity. If the gate is not there, the effect synth will be n_free'd (brutally cut off), probably before the nodes played by the source pattern have finished. In this case it would produce a sudden, brief jump in volume at the end. The gate, combined with the one-second release in the envelope, keeps the effect synth around long enough to allow its source synths to become silent first.</p>
74 <p class="p2"><br></p>
75 <p class="p3">Remember that streams made from patterns don't expose their internals. That means you can't adjust the parameters of an effect synth directly, because you have no way to find out what its node ID is. The example addresses this problem by allocating a couple of control buses for the amplitude values, and mapping the volume synths to those control buses. Then the little GUI needs only to update the control bus values.</p>
76 <p class="p2"><br></p>
77 <p class="p2"><br></p>
78 <p class="p7">// Demonstrates how Pfxb isolates signals on different buses</p>
79 <p class="p7">// The fx synth is a simple volume control here</p>
80 <p class="p7">// but it could be more complex</p>
81 <p class="p8"><br></p>
82 <p class="p9">(</p>
83 <p class="p10">SynthDef<span class="s3">(</span><span class="s2">\volumeCtl</span><span class="s3">, { </span>|out, amp = 1, gate = 1|</p>
84 <p class="p9"><span class="Apple-tab-span"> </span><span class="s1">var</span><span class="Apple-tab-span"> </span>sig = <span class="s1">In</span>.ar(out, 2) * amp;</p>
85 <p class="p9"><span class="Apple-tab-span"> </span>sig = sig * <span class="s1">EnvGen</span>.kr(<span class="s1">Env</span>(#[1, 1, 0], #[1, 1], -3, releaseNode: 1), gate, doneAction: 2);</p>
86 <p class="p9"><span class="Apple-tab-span"> </span><span class="s1">ReplaceOut</span>.ar(out, sig)</p>
87 <p class="p9">}).add;</p>
88 <p class="p8"><br></p>
89 <p class="p9">~vbus1 = <span class="s1">Bus</span>.control(s, 1).set(0.5);</p>
90 <p class="p9">~vbus2 = <span class="s1">Bus</span>.control(s, 1).set(0.5);</p>
91 <p class="p8"><br></p>
92 <p class="p9">~window = <span class="s1">Window</span>.new(<span class="s4">"mixers"</span>, <span class="s1">Rect</span>(10, 100, 320, 60));</p>
93 <p class="p9">~window.view.decorator = <span class="s1">FlowLayout</span>(~window.view.bounds, 2@2);</p>
94 <p class="p9"><span class="s1">EZSlider</span>(~window, 310@20, <span class="s4">"low part"</span>, <span class="s2">\amp</span>, { <span class="s1">|ez|</span> ~vbus1.set(ez.value) }, 0.5);</p>
95 <p class="p9">~window.view.decorator.nextLine;</p>
96 <p class="p9"><span class="s1">EZSlider</span>(~window, 310@20, <span class="s4">"high part"</span>, <span class="s2">\amp</span>, { <span class="s1">|ez|</span> ~vbus2.set(ez.value) }, 0.5);</p>
97 <p class="p9">~window.front.onClose_({ ~vbus1.free; ~vbus2.free });</p>
98 <p class="p9">)</p>
99 <p class="p8"><br></p>
100 <p class="p9">(</p>
101 <p class="p9">p = <span class="s1">Ppar</span>([</p>
102 <p class="p10"><span class="s3"><span class="Apple-tab-span"> </span></span>Pfxb<span class="s3">(</span>Pbind<span class="s3">(</span></p>
103 <p class="p9"><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span><span class="s2">\degree</span>, <span class="s1">Pseq</span>([0, 7, 4, 3, 9, 5, 1, 4], <span class="s1">inf</span>),</p>
104 <p class="p11"><span class="s3"><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span></span>\octave<span class="s3">, 4,</span></p>
105 <p class="p9"><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span><span class="s2">\dur</span>, 0.5</p>
106 <p class="p7"><span class="s3"><span class="Apple-tab-span"> </span>), </span><span class="s2">\volumeCtl</span><span class="s3">, </span><span class="s2">\amp</span><span class="s3">, ~vbus1.asMap),<span class="Apple-tab-span"> </span></span>// map to control bus here</p>
107 <p class="p10"><span class="s3"><span class="Apple-tab-span"> </span></span>Pfxb<span class="s3">(</span>Pbind<span class="s3">(</span></p>
108 <p class="p9"><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span><span class="s2">\degree</span>, <span class="s1">Pwhite</span>(0, 11, <span class="s1">inf</span>),</p>
109 <p class="p9"><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span><span class="s2">\dur</span>, 0.25</p>
110 <p class="p9"><span class="Apple-tab-span"> </span>), <span class="s2">\volumeCtl</span>, <span class="s2">\amp</span>, ~vbus2.asMap)<span class="Apple-tab-span"> </span><span class="s5">// ... and here</span></p>
111 <p class="p9">]).play;</p>
112 <p class="p9">)</p>
113 <p class="p8"><br></p>
114 <p class="p9">p.stop;</p>
115 <p class="p2"><br></p>
116 <p class="p3"><b>Third-party extension alert:</b> Pfx and its cousins work on the philosophy that a signal routing arrangement should be created as needed (when its subpattern is playing) and removed immediately when the pattern is finished. Another approach is to treat signal routing and effects as a persistent infrastructure, created and destroyed under the user's control (not the pattern's). JITLib's proxy system offers some support for this. MixerChannels (in the ddwMixerChannel quark) are a more explicit way. Any pattern can be played on a MixerChannel: <b>aMixer.play(aPattern)</b>.</p>
117 <p class="p2"><br></p>
118 <p class="p2"><br></p>
119 <p class="p12"><b>Pproto: Allocating other resources for the duration of a pattern</b></p>
120 <p class="p2"><br></p>
121 <p class="p3">It's also possible to load sound file or wavetable buffers or play synths as part of the preparation to run a Pbind-style pattern. When the Pbind stops, those resources would be removed automatically from the server.</p>
122 <p class="p2"><br></p>
123 <p class="p3">The mechanism to do this is a bit unlike most of the other protocols to use the server in SuperCollider. To create the resources, Pproto takes a function in which one or more Event objects contain the instructions to create them. These events should use specific event types, described in Pproto's help file. The pattern is able to clean up the resources because each event has an associated cleanup action (see the event types with cleanup class). Thus, Pproto needs only to remember the events representing the resources, and execute their cleanup actions at the end.</p>
124 <p class="p2"><br></p>
125 <p class="p3">The Pproto help file has several complex examples that are worth reading. Here is just one simple case that loads the standard a11wlk01.wav sound file and plays fragments from it.</p>
126 <p class="p2"><br></p>
127 <p class="p9">(</p>
128 <p class="p10">SynthDef<span class="s3">(</span><span class="s2">\playbuf</span><span class="s3">, { </span>|bufnum, start, dur = 1, amp = 0.2, out|</p>
129 <p class="p9"><span class="Apple-tab-span"> </span><span class="s1">var</span><span class="Apple-tab-span"> </span>sig = <span class="s1">PlayBuf</span>.ar(1, bufnum, <span class="s1">BufRateScale</span>.ir(bufnum), 0, start);</p>
130 <p class="p9"><span class="Apple-tab-span"> </span>sig = sig * amp * <span class="s1">EnvGen</span>.kr(<span class="s1">Env</span>.linen(0.01, dur, 0.01), doneAction: 2);</p>
131 <p class="p9"><span class="Apple-tab-span"> </span><span class="s1">Out</span>.ar(out, sig ! 2)</p>
132 <p class="p9">}).add;</p>
133 <p class="p9">)</p>
134 <p class="p8"><br></p>
135 <p class="p9">(</p>
136 <p class="p9"><span class="s1">TempoClock</span>.default.tempo = 1;</p>
137 <p class="p9">p = <span class="s1">Pproto</span>({</p>
138 <p class="p9"><span class="Apple-tab-span"> </span>~buf = (type: <span class="s2">\allocRead</span>, path: <span class="s4">"sounds/a11wlk01.wav"</span>).yield;</p>
139 <p class="p10"><span class="s3">}, </span>Pbind<span class="s3">(</span></p>
140 <p class="p11"><span class="s3"><span class="Apple-tab-span"> </span></span>\instrument<span class="s3">, </span>\playbuf<span class="s3">,</span></p>
141 <p class="p7"><span class="s3"><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span></span>// access resources in the protoevent by Pkey</p>
142 <p class="p11"><span class="s3"><span class="Apple-tab-span"> </span></span>\bufnum<span class="s3">, </span><span class="s1">Pkey</span><span class="s3">(</span>\buf<span class="s3">),</span></p>
143 <p class="p9"><span class="Apple-tab-span"> </span><span class="s2">\dur</span>, <span class="s1">Pwhite</span>(1, 4, <span class="s1">inf</span>) * 0.25,</p>
144 <p class="p7"><span class="s3"><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span></span>// upper bound of Pwhite is based on duration</p>
145 <p class="p7"><span class="s3"><span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span></span>// so that start + (dur * samplerate) never goes past the buffer's end</p>
146 <p class="p9"><span class="Apple-tab-span"> </span><span class="s2">\start</span>, <span class="s1">Pwhite</span>(0, 188893 - (<span class="s1">Pkey</span>(<span class="s2">\dur</span>) * 44100), <span class="s1">inf</span>)</p>
147 <p class="p9">)).play;</p>
148 <p class="p9">)</p>
149 <p class="p8"><br></p>
150 <p class="p7">// shows a buffer number allocated ('true' ContiguousBlock)</p>
151 <p class="p9">s.bufferAllocator.debug;</p>
152 <p class="p8"><br></p>
153 <p class="p9">p.stop;</p>
154 <p class="p8"><br></p>
155 <p class="p7"><span class="s3">s.bufferAllocator.debug;<span class="Apple-tab-span"> </span></span>// after stop, the buffer is gone</p>
156 <p class="p2"><br></p>
157 <p class="p2"><br></p>
158 <p class="p13"><span class="s3">Previous:<span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span><a href="PG_06e_Language_Control.html"><span class="s6">PG_06e_Language_Control</span></a></span></p>
159 <p class="p13"><span class="s3">Next:<span class="Apple-tab-span"> </span><span class="Apple-tab-span"> </span><a href="PG_06g_Data_Sharing.html"><span class="s6">PG_06g_Data_Sharing</span></a></span></p>
160 </body>
161 </html>